feat: wire after_specify and after_plan hook events into command templates#1825
feat: wire after_specify and after_plan hook events into command templates#1825davidniu-0914 wants to merge 6 commits intogithub:mainfrom
after_specify and after_plan hook events into command templates#1825Conversation
…lan (github#1788) - Update EXTENSION-API-REFERENCE.md to reflect current hook implementation status. - Add before_tasks and before_implement hooks to EXTENSION-DEVELOPMENT-GUIDE.md. - Standardize CRITICAL execution instructions for mandatory hooks across all templates (specify, plan, tasks, implement). - Sync documentation versions and pyproject.toml to 0.2.1 to match upstream. - Update Last Updated dates in extension guides.
There was a problem hiding this comment.
Pull request overview
This PR updates the Spec Kit command templates and extension documentation so that the lifecycle hook events for before_specify/after_specify and before_plan/after_plan are represented consistently alongside existing hook points, and bumps the project/docs version to 0.2.1.
Changes:
- Add pre- and post- hook instructions for
specifyandplancommand templates (before_*andafter_*events). - Strengthen “mandatory hook” execution instructions across core templates (add explicit CRITICAL “execute immediately” language).
- Bump version to
0.2.1and update extension guides + changelog accordingly.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| templates/commands/specify.md | Adds before_specify and after_specify hook instructions + CRITICAL execution requirements. |
| templates/commands/plan.md | Adds before_plan and after_plan hook instructions + CRITICAL execution requirements. |
| templates/commands/tasks.md | Adds CRITICAL execution requirement wording for mandatory hooks. |
| templates/commands/implement.md | Adds CRITICAL execution requirement wording for mandatory hooks. |
| src/specify_cli/extensions.py | Updates docstrings/examples for hook event names to include specify/plan events. |
| pyproject.toml | Bumps package version to 0.2.1. |
| extensions/EXTENSION-USER-GUIDE.md | Updates stated minimum/version references and last-updated metadata. |
| extensions/EXTENSION-DEVELOPMENT-GUIDE.md | Expands documented hook points to include specify/plan + before_implement, updates examples. |
| extensions/EXTENSION-API-REFERENCE.md | Documents additional standard hook events and adds CRITICAL mandatory-hook instruction. |
| CHANGELOG.md | Adds an Unreleased entry for the new hook wiring. |
Comments suppressed due to low confidence (2)
templates/commands/plan.md:87
- The post-plan hook filtering here will drop hooks that omit
enabled(which are enabled by default inHookExecutor) and will skip all hooks that setcondition, even though the codebase supports condition evaluation. This makes conditional hooks impossible to trigger from the template-driven workflow.
- Filter to only hooks where `enabled: true`
- For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions:
- If the hook has no `condition` field, or it is null/empty, treat the hook as executable
- If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation
- For each executable hook, output the following based on its `optional` flag:
templates/commands/specify.md:33
- Hook filtering in the template doesn’t match the actual hook config behavior in
HookExecutor: hooks default to enabled when theenabledfield is missing (h.get('enabled', True)), so instructing the agent to keep onlyenabled: truewould incorrectly drop hooks without an explicitenabledkey. Also, skipping hooks with a non-emptyconditionmeans conditional hooks will never run from the template flow even though the codebase supports condition evaluation; consider treating conditions as evaluatable (same rules asHookExecutor.should_execute_hook) or at least not skipping them outright.
- Filter to only hooks where `enabled: true`
- For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions:
- If the hook has no `condition` field, or it is null/empty, treat the hook as executable
- If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
templates/commands/plan.md
Outdated
| - Filter to only hooks where `enabled: true` | ||
| - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: | ||
| - If the hook has no `condition` field, or it is null/empty, treat the hook as executable | ||
| - If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation | ||
| - For each executable hook, output the following based on its `optional` flag: | ||
| - **Optional hook** (`optional: true`): |
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback. If not applicable, please explain why
# Conflicts: # CHANGELOG.md # pyproject.toml
Updated the prompt to treat omitted `enabled` flags as true and pass all hooks (including those with `condition` fields) to the HookExecutor, correctly addressing the PR review feedback. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…o feature/add-spec-plan-hooks
Updated the prompt to treat omitted `enabled` flags as true and pass all hooks (including those with `condition` fields) to the HookExecutor, correctly addressing the PR review feedback.
There was a problem hiding this comment.
Pull request overview
This PR updates the Spec Kit command templates and extension documentation to include missing lifecycle hook events (notably after_specify / after_plan, plus corresponding before_* events) and to standardize mandatory-hook execution instructions across core commands.
Changes:
- Add
before_specify/after_specifyandbefore_plan/after_planhook-check instructions to thespecifyandplancommand templates. - Strengthen “CRITICAL: execute immediately” instructions for mandatory hooks in
tasksandimplementtemplates. - Update extension docs (hook event lists/examples) and add a CHANGELOG entry; bump
pyproject.tomlversion.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| templates/commands/tasks.md | Adds stronger mandatory-hook execution wording for pre/post task hooks. |
| templates/commands/specify.md | Adds pre- and post- hook checking instructions for before_specify/after_specify. |
| templates/commands/plan.md | Adds pre- and post- hook checking instructions for before_plan/after_plan. |
| templates/commands/implement.md | Adds stronger mandatory-hook execution wording for pre/post implement hooks. |
| src/specify_cli/extensions.py | Updates docstrings to reference additional hook event examples. |
| pyproject.toml | Bumps the package version. |
| extensions/EXTENSION-USER-GUIDE.md | Updates stated Spec Kit version and last-updated footer. |
| extensions/EXTENSION-DEVELOPMENT-GUIDE.md | Expands documented standard hook points and updates hook examples. |
| extensions/EXTENSION-API-REFERENCE.md | Documents additional hook events and adds “CRITICAL” mandatory-hook instruction. |
| CHANGELOG.md | Adds an Unreleased entry for the new hook wiring and adjusts indentation of nested bullets. |
Comments suppressed due to low confidence (2)
templates/commands/specify.md:220
- This post-hook section instructs the agent to ignore
conditionentirely and treat all non-disabled hooks as executable candidates. That diverges fromHookExecutor.check_hooks_for_event, which filters byshould_execute_hook()and will skip hooks when conditions are not met or cannot be evaluated. To avoid executing hooks unexpectedly, this should either (1) mirror HookExecutor behavior for conditions, or (2) explicitly state that conditional hooks must not be auto-executed by the agent.
- From the discovered hooks, ignore only those where `enabled` is explicitly set to `false`. If `enabled` is omitted, treat the hook as enabled.
- Do **not** attempt to interpret or evaluate hook `condition` expressions, and do **not** filter hooks based on the presence or contents of `condition`. Condition evaluation is handled by the `HookExecutor.should_execute_hook` implementation.
- Treat all hooks that are not explicitly disabled (that is, all hooks where `enabled` is not `false`) as executable candidates.
- For each executable hook, output the following based on its `optional` flag:
templates/commands/plan.md:85
- This post-hook guidance tells the agent not to filter on
condition, but HookExecutor’scheck_hooks_for_event()does apply condition filtering viashould_execute_hook(). Without condition evaluation, the agent can execute hooks that are supposed to be gated off. Recommend updating the template to avoid auto-executing conditional hooks unless their conditions can be evaluated consistently with HookExecutor.
- From the discovered hooks, ignore only those where `enabled` is explicitly set to `false`. If `enabled` is omitted, treat the hook as enabled.
- Do **not** attempt to interpret or evaluate hook `condition` expressions, and do **not** filter hooks based on the presence or contents of `condition`. Condition evaluation is handled by the `HookExecutor.should_execute_hook` implementation.
- Treat all hooks that are not explicitly disabled (that is, all hooks where `enabled` is not `false`) as executable candidates.
- For each executable hook, output the following based on its `optional` flag:
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| *Last Updated: 2026-01-28* | ||
| *Spec Kit Version: 0.1.0* | ||
| *Last Updated: 2026-03-13* | ||
| *Spec Kit Version: 0.2.1* |
| *Last Updated: 2026-03-13* | ||
| *API Version: 1.0* | ||
| *Spec Kit Version: 0.1.0* | ||
| *Spec Kit Version: 0.2.1* |
| [project] | ||
| name = "specify-cli" | ||
| version = "0.3.0" | ||
| version = "0.3.1" |
| - Treat all enabled hooks as executable for the purposes of this plan, regardless of whether they define a `condition` | ||
| - For each executable hook, output the following based on its `optional` flag: |
| - Treat all enabled hooks as executable for the purposes of this plan, regardless of whether they define a `condition` | ||
| - For each executable hook, output the following based on its `optional` flag: |
mnriem
left a comment
There was a problem hiding this comment.
Please address additional Copilot feedback.
Description
This PR aligns the extension hooks documentation and command templates for the specify and plan commands, resolving Issue #1788. It ensures that all core command templates (specify.md, plan.md, tasks.md,
implement.md) contain consistent CRITICAL execution instructions for mandatory hooks, preventing AI agents from proceeding before hook execution. Additionally, it synchronizes the project version to 0.2.1 across
pyproject.toml and all extension guides to match the upstream repository.
Testing
AI Disclosure
This PR was prepared with the assistance of Gemini CLI to synchronize version numbers across multiple files, standardize hook instructions in markdown templates for behavioral consistency, and ensure
documentation accuracy relative to the implemented features.